﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Sunny.Lib.CustomeAttribute
{
    [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
    public class PrimaryKeyAttribute : Attribute
    {
        public PrimaryKeyAttribute()
        {

        }
    }

    [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
    public class IdentityAttribute : Attribute
    {
        public IdentityAttribute()
        {

        }
    }

    [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
    // To specify the name of column of table in database.
    public class ColumnNameAttribute : Attribute
    {
        public string ColumnName { get; set; }
        public ColumnNameAttribute(string columnName)
        {
            ColumnName = columnName;
        }
    }

    public class ExcludeLogAttribute : Attribute
    {
    }

    public class CustomeAttributeHelper
    {
        public static void GetCustomeAttributes(MemberInfo attributeTarget)
        {
            IList<CustomAttributeData> attributes = CustomAttributeData.GetCustomAttributes(attributeTarget);
        }

        public static bool IsDefine(MemberInfo attributeTarget, Type attributeType, bool searchChild = false)
        {
            bool isDefine = false;

            if (attributeType == null)
            {
                return isDefine; 
            }

            if ((attributeTarget.GetCustomAttributes(attributeType, searchChild).Length > 0))
            {
                isDefine = true;
            }

            return isDefine;
        }

        /// <summary>
        /// return whether attributeTarget at least contains one of attributeTypes
        /// </summary>
        /// <param name="attributeTarget"></param>
        /// <param name="attributeTypes"></param>
        /// <param name="searchChild"></param>
        /// <returns></returns>
        public static bool IsDefineAtLeastOne(MemberInfo attributeTarget, List<Type> attributeTypes, bool searchChild = false)
        {
            bool isDefine = false;

            foreach (Type p in attributeTypes)
            {
                if (IsDefine(attributeTarget, p, searchChild))
                {
                    isDefine = true;
                    break;
                }
            }

            return isDefine;
        }

        /// <summary>
        /// return whether attributeTarget contains all of attributeTypes 
        /// </summary>
        /// <param name="attributeTarget"></param>
        /// <param name="attributeTypes"></param>
        /// <param name="searchChild"></param>
        /// <returns></returns>
        public static bool IsDefineAll(MemberInfo attributeTarget, List<Type> attributeTypes, bool searchChild = false)
        {
            bool isDefine = true;

            foreach (Type p in attributeTypes)
            {
                if (!IsDefine(attributeTarget, p, searchChild))
                {
                    isDefine = false;
                    break;
                }
            }

            return isDefine;
        }
    }
}
